﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using DevMaker.SIC.Model;
using log4net;

namespace DevMaker.SIC.Dao {
    public class CierreDao {

        private static readonly ILog Log =
            LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public Cierre Crear(Turno turno, Cierre cierre, SqlTransaction transaction) {
            const string storeName = "sp_cierre_turnos_c";
            try {
                cierre.FechaNegocio = cierre.Fecha;
                if (cierre.FechaNegocio.Hour < 6)
                    cierre.FechaNegocio = cierre.FechaNegocio.AddDays(-1);
                cierre.FechaNegocio = new DateTime(cierre.FechaNegocio.Year, cierre.FechaNegocio.Month,
                                                   cierre.FechaNegocio.Day);

                var ht = ObtieneVentasDeVista(turno);
                if (ht.Contains("IdSessionVista"))
                    cierre.IdSessionVista = Convert.ToInt64(ht["IdSessionVista"]);
                else
                    cierre.IdSessionVista = 0;

                if (ht.Contains("FechaNegocioVista"))
                    cierre.FechaNegocioVista = Convert.ToDateTime(ht["FechaNegocioVista"]);
                else
                    cierre.FechaNegocioVista = cierre.FechaNegocio;

                var turnoCuadrado = true;
                foreach (var cierreDetalle in cierre.Detalle) {
                    cierreDetalle.CantidadVendida = Convert.ToInt64(ht[cierreDetalle.Producto.Id.ToString()]);
                    if (cierreDetalle.Cuadrado == false) {
                        cierre.DiferenciaEnPesos += cierreDetalle.Diferencia * cierreDetalle.PrecioUnitario;
                        cierre.DiferenciaProductos += cierreDetalle.Diferencia;
                        turnoCuadrado = false;
                    }
                }

                var command = new SqlCommand(storeName, transaction.Connection) { Transaction = transaction, CommandType = CommandType.StoredProcedure };
                command.Parameters.AddWithValue("@id_sucursal", turno.Sucursal.Id);
                command.Parameters.AddWithValue("@cod_sucursal", turno.Sucursal.Codigo);
                command.Parameters.AddWithValue("@id_turno", turno.Id);
                command.Parameters.AddWithValue("@id_supervisor", cierre.Supervisor.Id);
                command.Parameters.AddWithValue("@id_punto_venta", turno.PuntoVenta.Code);
                command.Parameters.AddWithValue("@fecha", cierre.Fecha);
                command.Parameters.AddWithValue("@turno_cuadrado", turnoCuadrado);
                if (!String.IsNullOrEmpty(cierre.Observacion))
                    command.Parameters.AddWithValue("@observacion", cierre.Observacion);
                else
                    command.Parameters.AddWithValue("@observacion", DBNull.Value);

                command.Parameters.AddWithValue("@diferencia_pesos", cierre.DiferenciaEnPesos);
                command.Parameters.AddWithValue("@diferencia_productos", cierre.DiferenciaProductos);

                command.Parameters.AddWithValue("@fecha_negocio", cierre.FechaNegocio);
                command.Parameters.AddWithValue("@session_pos_id", cierre.IdSessionVista);
                command.Parameters.AddWithValue("@session_pos_fecha_negocio", cierre.FechaNegocioVista);

                var outParam = command.Parameters.Add("@id", SqlDbType.BigInt);
                outParam.Direction = ParameterDirection.Output;
                command.ExecuteScalar();
                cierre.Id = Convert.ToInt32(outParam.Value);
                var cierreDetalleDao = new CierreDetalleDao();
                foreach (var cd in cierre.Detalle) {
                    cierreDetalleDao.Crear(turno, cierre, cd, transaction);
                }
            } catch (Exception ex) {
                Log.Error(ex);
                throw ex;
            }
            return cierre;
        }

        public Cierre ObtienePorTurno(Turno turno) {
            const string storeName = "sp_cierre_turnos_por_id_turno";
            Cierre cierre = null;
            var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SIC_Connection"].ToString());

            try {
                conn.Open();
                var command = new SqlCommand(storeName, conn) { CommandType = CommandType.StoredProcedure };
                command.Parameters.AddWithValue("@id", turno.Id);
                var reader = command.ExecuteReader();
                while (reader.Read()) {
                    if (cierre == null) {
                        cierre = new Cierre();
                        cierre.ReadFromDataReader(reader);
                    }
                    var detalle = new CierreDetalle();
                    detalle.ReadFromDataReader(reader);
                    cierre.Detalle.Add(detalle);
                }
            } catch (Exception ex) {
                Log.Error(ex);
                throw;
            } finally {
                if (conn.State != ConnectionState.Closed)
                    conn.Close();
            }
            return cierre;
        }

        public Hashtable ObtieneVentasDeVista(Turno turno) {
            var ht = new Hashtable();
            const string storeName = "SP_obtiene_ventas_de_vista_L";
            var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SIC_Connection"].ToString());

            try {
                conn.Open();
                var command = new SqlCommand(storeName, conn) { CommandType = CommandType.StoredProcedure };
                command.Parameters.AddWithValue("@id_cajero", turno.Cajero.Id);
                var reader = command.ExecuteReader();
                while (reader.Read()) {
                    if (!ht.Contains("IdSessionVista"))
                        ht.Add("IdSessionVista", Convert.ToInt64(reader["IdSessionVista"]));

                    if (!ht.Contains("FechaNegocioVista"))
                        ht.Add("FechaNegocioVista", Convert.ToDateTime(reader["FechaNegocioVista"]));

                    var idProducto = reader["Item_strItemId"];

                    if (!ht.Contains(idProducto))
                        ht.Add(idProducto.ToString(), Convert.ToUInt64(reader["cantidadVendida"]));



                }
            } catch (Exception ex) {
                Log.Error(ex);
                throw;
            } finally {
                if (conn.State != ConnectionState.Closed)
                    conn.Close();
            }
            return ht;
        }
    }
}

